class Player extends AcGameObject {
    constructor(playground, x, y, radius, color, speed, is_me) {
        super();
        this.playground = playground;
        this.ctx = this.playground.game_map.ctx;
        this.x = x;
        this.y = y;
        this.vx = 0;
        this.vy = 0;
        this.damage_x = 0;
        this.damage_y = 0;
        this.damage_speed = 0;
        this.move_length = 0;
        this.radius = radius;
        this.color = color;
        this.speed = speed;
        this.is_me = is_me;
        this.absolute_defenses = [];
        this.my_big_skill = true;
        this.eps = 0.1;
        this.friction = 0.9;
        this.spent_time = 0;
        this.last_absolute_defense_time = -100;//用于计算绝对防御技能cd
        this.last_iceball_time = -100; //用于计算iceball技能cd
        this.controlled_start_time = 0;
        this.controlled_status = false;
        this.iceball_enable_time = 1; //冰冻持续时间
        this.absolute_defense_cd = 3;
        this.iceball_cd = 5;
        this.last_fireball_time = -100;
        this.fireball_cd = 2;
        this.fireball_damage = this.playground.height * 0.005;
        this.fixed_fireball_num = 10;
        this.fireball_num = this.fixed_fireball_num; //每轮可用的fireball个数
        this.fireball_status = true;//fireball可用状态
        this.alive = true;
        this.cur_skill = null;

        if(this.is_me){
            new Qskill(this.playground, 'orange', this);
            new Wskill(this.playground, 'gold', this);
            new Eskill(this.playground, 'red', this);
            new Rskill(this.playground, 'blue', this);
            new Blood(this.playground, 'grey', this);
            new RealBlood(this.playground, 'red', this);
        }
    }

    start() {
        if (this.is_me) {
            this.add_listening_events();
        } else {
            let tx = Math.random() * this.playground.width;
            let ty = Math.random() * this.playground.height;
            this.move_to(tx, ty);
        }
    }

    add_listening_events() {
        let outer = this;
        this.playground.game_map.$canvas.on("contextmenu", function () {
            return false;
        });
        this.playground.game_map.$canvas2.on("contextmenu", function () {
            return false;
        });
        this.playground.game_map.$canvas.mousedown(function (e) {
            const rect = outer.ctx.canvas.getBoundingClientRect();
            if (e.which === 3) {
                outer.move_to(e.clientX - rect.left, e.clientY - rect.top);
            } else if (e.which === 1) {
                if (outer.cur_skill === "fireball") {
                    outer.shoot_fireball(e.clientX - rect.left, e.clientY - rect.top);
                }
                if (outer.cur_skill === "absolute_defense") {
                    outer.shoot_absolute_defense(e.clientX - rect.left, e.clientY - rect.top);
                }
                if (outer.cur_skill === "bigskill") {
                    outer.shoot_big_skill(e.clientX - rect.left, e.clientY - rect.top);
                }
                if (outer.cur_skill === "iceball") {
                    outer.shoot_iceball(e.clientX - rect.left, e.clientY - rect.top);
                }
                outer.cur_skill = null;
            }
        });

        $(window).keydown(function (e) {
            if (e.which === 81) {  // q
                outer.cur_skill = "fireball";
                return false;
            }
            if (e.which === 87) {  // w
                outer.cur_skill = "absolute_defense";
                return false;
            }
            if (e.which === 69 && outer.my_big_skill) {  // e
                outer.cur_skill = "bigskill";
                return false;
            }
            if (e.which === 82) {  // r
                outer.cur_skill = "iceball";
                return false;
            }
        });
    }

    shoot_fireball(tx, ty) {
        if (!this.alive) return false;
        if (this.controlled_status) return false;
        if(this.spent_time - this.last_fireball_time < this.fireball_cd) return false;
        if(!this.fireball_status) {
            this.fireball_num = this.fixed_fireball_num;
            this.fireball_status = true;
        }
        this.fireball_num --;
        if(!this.fireball_num) {
            this.last_fireball_time = this.spent_time;
            this.fireball_status = false;
        }
        let x = this.x, y = this.y;
        let radius = this.playground.height * 0.01;
        let angle = Math.atan2(ty - this.y, tx - this.x);
        let vx = Math.cos(angle), vy = Math.sin(angle);
        let color = "orange";
        let speed = this.playground.height * 0.5;
        let move_length = this.playground.height * 1;
        new FireBall(this.playground, this, x, y, radius, vx, vy, color, speed, move_length, this.fireball_damage);
    }

    shoot_absolute_defense(tx, ty) {
        if (!this.alive) return false;
        if (this.controlled_status) return false;
        if (this.spent_time - this.last_absolute_defense_time < this.absolute_defense_cd) return false;
        this.last_absolute_defense_time = this.spent_time;
        let x = this.x, y = this.y;
        let radius = this.playground.height * 0.15;
        let angle = Math.atan2(ty - this.y, tx - this.x);
        let vx = Math.cos(angle), vy = Math.sin(angle);
        let color = "gold";
        let alive_time = 1;
        this.absolute_defenses.push(new absolute_defense(this.playground, this, x, y, radius, vx, vy, color, alive_time, 0));
    }

    shoot_big_skill(tx, ty) {
        if (!this.alive) return false;
        if (this.controlled_status) return false;
        if(!this.my_big_skill) return false;
        this.my_big_skill = false;
        let x = this.x, y = this.y;
        let radius = this.playground.height * 20;
        let angle = Math.atan2(ty - this.y, tx - this.x);
        let vx = Math.cos(angle), vy = Math.sin(angle);
        let color = "red";
        let speed = this.playground.height * 0.5;
        let move_length = this.playground.height * 1;
        new BigSkill(this.playground, this, x, y, radius, vx, vy, color, speed, move_length, this.playground.height * 0.01);
    }

    shoot_iceball(tx, ty) {
        if (!this.alive) return false;
        if (this.controlled_status) return false;
        if (this.spent_time - this.last_iceball_time < this.iceball_cd) return false;
        this.last_iceball_time = this.spent_time;
        let x = this.x, y = this.y;
        let radius = this.playground.height * 0.03;
        let angle = Math.atan2(ty - this.y, tx - this.x);
        let vx = Math.cos(angle), vy = Math.sin(angle);
        let color = "blue";
        let speed = this.playground.height * 0.5;
        let move_length = this.playground.height * 1;
        new IceBall(this.playground, this, x, y, radius, vx, vy, color, speed, move_length, 0);
    }

    get_dist(x1, y1, x2, y2) {
        let dx = x1 - x2;
        let dy = y1 - y2;
        return Math.sqrt(dx * dx + dy * dy);
    }

    move_to(tx, ty) {
        if (this.controlled_status && this.spent_time - this.controlled_start_time < this.iceball_enable_time) {
            this.move_length = 0;
        }
        else {
            this.controlled_status = false;
            this.move_length = this.get_dist(this.x, this.y, tx, ty);
            let angle = Math.atan2(ty - this.y, tx - this.x);
            // if(this.is_me) console.log(angle);
            this.vx = Math.cos(angle);
            this.vy = Math.sin(angle);
        }


    }

    judge_me_alive() {
        for (let i = 0; i < this.playground.players.length; i++) {
            if (this.playground.players[i].is_me === true) {
                return true;
            }
        }
        return false;
    }
    is_attacked(angle, damage) {
        // if (this.is_me) console.log("attacked!!!")
        for (let i = 0; i < 20 + Math.random() * 10; i++) {
            let x = this.x, y = this.y;
            let radius = this.radius * Math.random() * 0.1;
            let angle = Math.PI * 2 * Math.random();
            let vx = Math.cos(angle), vy = Math.sin(angle);
            let color = this.color;
            let speed = this.speed * 10;
            let move_length = this.radius * Math.random() * 5;
            new Particle(this.playground, x, y, radius, vx, vy, color, speed, move_length);
        }
        this.radius -= damage;
        if (this.radius <= this.playground.height * 0.011) {
            this.alive = false;
            this.on_destroy();
            this.destroy();
            // console.log(this.playground.players.length);
            if (this.judge_me_alive() && this.playground.players.length == 1) {
                // console.log("YOU  WIN!!!");
                let win_menu = new AcGameMenu_win(this);
                this.playground.hide();
                win_menu.show();
                // this.playground.root.menu.show();
                // return false;
            }
            if (this.is_me && this.alive == false && this.playground.players.length > 0) {
                // console.log("YOU  LOSE!!!");
                let lose_menu = new AcGameMenu_lose(this);
                this.playground.hide();
                lose_menu.show();
                // this.playground.root.menu.show();
                // return false;
            }
            return false;
        }
        this.damage_x = Math.cos(angle);
        this.damage_y = Math.sin(angle);
        if (damage > 0) this.damage_speed = damage * 100;
        else this.damage_speed = this.playground.height * 0.5;
        if (damage > 0) this.speed *= 0.9;
    }

    is_controlled() {
        // console.log("be_controlled!!!")
        this.controlled_start_time = this.spent_time;
        this.controlled_status = true;
        for (let i = 0; i < 20 + Math.random() * 10; i++) {
            let x = this.x, y = this.y;
            let radius = this.radius * Math.random() * 0.1;
            let angle = Math.PI * 2 * Math.random();
            let vx = Math.cos(angle), vy = Math.sin(angle);
            let color = this.color;
            let speed = this.speed * 10;
            let move_length = this.radius * Math.random() * 5;
            new Particle(this.playground, x, y, radius, vx, vy, color, speed, move_length);
        }
    }

    judge_out_map() {
        let flag = false;
        if (this.x - this.radius <= 0) {
            this.x = 0 + this.radius;
            this.vx = this.vy = 0;
            this.move_length = 0;
            flag = true;
        }
        if (this.x + this.radius >= this.playground.width) {
            this.x = this.playground.width - this.radius;
            this.vx = this.vy = 0;
            this.move_length = 0;
            flag = true;
        }
        if (this.y - this.radius <= 0) {
            this.y = 0 + this.radius;
            this.vx = this.vy = 0;
            this.move_length = 0;
            flag = true;
        }
        if (this.y + this.radius >= this.playground.height) {
            this.y = this.playground.height - this.radius;
            this.vx = this.vy = 0;
            this.move_length = 0;
            flag = true;
        }
        return flag;
    }

    update() {
        // if(this.is_me){
        //     console.log(this.my_big_skill);
        //     console.log(this.cur_skill);
        // }
        this.spent_time += this.timedelta / 1000;
        if (this.controlled_status && this.spent_time - this.controlled_start_time >= this.iceball_enable_time) this.controlled_status = false;
        if (!this.is_me && this.spent_time > 0.5 && Math.random() < 1 / 60.0) {
        // if (!this.is_me && this.spent_time > 1) { 
            let player = this.playground.players[Math.floor(Math.random() * this.playground.players.length)];
            while (player === this && this.playground.players.length > 1) player = this.playground.players[Math.floor(Math.random() * this.playground.players.length)];
            // while(!player.is_me&& this.playground.players.length > 6) player = this.playground.players[Math.floor(Math.random() * this.playground.players.length)];
            let tx = player.x + player.speed * this.vx * this.timedelta / 1000 * 0.3;
            let ty = player.y + player.speed * this.vy * this.timedelta / 1000 * 0.3;
            let skill_num = Math.floor(Math.random() * 7)
            if (skill_num == 0 || skill_num == 1 || skill_num == 2 || skill_num == 3 || skill_num == 5) this.shoot_fireball(tx, ty);
            if (skill_num == 4) this.shoot_absolute_defense(tx, ty);
            // if (skill_num == 5) this.shoot_big_skill(tx, ty);
            if (skill_num == 6) this.shoot_iceball(tx, ty);
        }

        if (this.damage_speed > 100) {
            this.vx = this.vy = 0;
            this.move_length = 0;
            this.x += this.damage_x * this.damage_speed * this.timedelta / 1000;
            this.y += this.damage_y * this.damage_speed * this.timedelta / 1000;
            this.damage_speed *= this.friction;
            if (this.judge_out_map()) this.damage_speed = 0;
        } else {
            if (this.move_length < this.eps || this.controlled_status) {
                this.move_length = 0;
                this.vx = this.vy = 0;
                if (!this.is_me) {
                    let tx = Math.random() * this.playground.width;
                    let ty = Math.random() * this.playground.height;
                    // let tx = this.playground.players[Math.floor(Math.random() * this.playground.players.length)].x;
                    // let ty = this.playground.players[Math.floor(Math.random() * this.playground.players.length)].y;
                    this.move_to(tx, ty);
                }
            }
            else {
                // let moved = this.move_length;
                let moved = Math.min(this.move_length, this.speed * this.timedelta / 1000);
                this.x += this.vx * moved;
                this.y += this.vy * moved;
                this.judge_out_map()
                this.move_length -= moved;
            }
        }
        this.render();
    }

    render() {
        this.ctx.beginPath();
        this.ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
        this.ctx.fillStyle = this.color;
        this.ctx.fill();
    }

    on_destroy() {
        for (let i = 0; i < this.playground.players.length; i++) {
            if (this.playground.players[i] === this) {
                this.playground.players.splice(i, 1);
            }
        }
    }
}
